TITL DAI FIRMWARE 3E859-3E9FF V1.1 ORG :E859 * * * ****************************** * CHECK STATEMENT TERMINATOR * ****************************** * * Get character from line and checks if it is * a correct terminator (':' or car.ret). * * Exit: Z=1: correct terminator. * Z=0: incorrect. * BCDEHL preserved. A corrupted. * TSEOC CALL :DDD2 Get char from line, neglect REM tab + space CPI :3A Is it ':' ? RZ CPI :0D Is it 'CR' ? RET * ********************************** * CHECK IF NEXT CHARACTER IS ',' * ********************************** * * Exit: C updated, AF corrupted, BDEHL preserved. * L3E131 CALL :E867 Check if next char is ',' DATA :2C RET * ************************ * CHECK NEXT CHARACTER * ************************ * * Routine finds next valid character in input. If * it is not the character expected: syntax error. * * Entry: C : Points to input. * ASCII-value of character to compare with * on stack. * Exit: If correct: C updated, AF corrupted, * BDEHL preserved. * ECHRI XTHL HL pnts to expected char CALL :DDD2 Get char from line, neglect REM tab + space CMP M Is it expected one ? JNZ :DA0B Run 'SYNTAX ERROR' if not INR C Pnts to next input INX H ) XTHL ) Update SP RET * ******************************* * ENCODE 'ERASE' - (not used) * ******************************* * * The BASIC command 'ERASE' is cancelled. * L3E133 LXI D,:E678 Addr routine encode array REM without arguments JMP :E12A Encode * ****************************** * INPUT FPT NUMBER INTO MACC * ****************************** * * Entry: Z=1: Change sign too. * Exit: C updated, ABDEHL preserved. * CY=0: Error. * L3E134 CALL :C01E Input FPT number to MACC RNZ Ready if Z=0 RST 4 Else change sign MACC DATA :1B RET * ******************************* * STORE QUOTED TEXT INTO EBUF * ******************************* * * Entry: C points to 1st '"'. * L3E135 INR C JMP :E69C Store text in EBUF * ******************************** * STORE A HEX NUMBER INTO EBUF * ******************************** * * Entry: C points to '#' of hex number. * EHEX INR C JMP :E590 Hex nr into EBUF * ********************************** * ENCODE AN INT NUMBER INTO EBUF * ********************************** * L3E137 CALL :E8AF #14 into EBUF CPI :23 '#' ? JZ :E899 Then jump CALL :E57B INT nr into EBUF L3E139 JNC :E8B7 Evt run 'SYNTAX ERROR' JMP :E15C Quit REM * If hex number: REM L3E138 CALL :E884 Hex nr into EBUF JMP :E893 * DATA :FF DATA :FF DATA :FF * ***************** * ENCODE 'DATA' * ***************** * EDATA MOV A,L CPI :42 JNZ :DA0B Run 'SYNTAX ERROR' if not JMP :E366 Encode text * ******************************** * part of END ENCODING (3E6B5) * ******************************** * L3E140 INR E JMP :E6C8 * ********************************* * CODE FOR INT NUMBER INTO EBUF * ********************************* * * Gets also next character to encode. * L3E141 MVI M,:14 INT code (#14) in EBUF CALL :E018 Update EBUF pointer JMP :DDD2 Get char from line, neglect REM tab + space * **************************************** * ERROR EXIT 'ENCODE INT NR INTO EBUF' * **************************************** * LXI H,:E39F ] (0) Addr routine 'STORE REM DATA' PUSH H ] Preserve it as returnaddr LDA :0040 ] Get POROM ANI :3F ] Select bank 0 PUSH PSW ] JMP :C6E6 ] Bank return * DATA :FF * ************************************** * ASCII TABLE UPPER CASE (UNSHIFTED) * ************************************** * KEYTU DATA :30 0 DATA :31 1 DATA :32 2 DATA :33 3 DATA :34 4 DATA :35 5 DATA :36 6 DATA :37 7 DATA :38 8 DATA :39 9 DATA :3A : DATA :3B ; DATA :2C , DATA :2D - DATA :2E . DATA :2F / DATA :0D car ret DATA :41 A DATA :42 B DATA :43 C DATA :44 D DATA :45 E DATA :46 F DATA :47 G DATA :48 H DATA :49 I DATA :4A J DATA :4B K DATA :4C L DATA :4D M DATA :4E N DATA :4F O DATA :50 P DATA :51 Q DATA :52 R DATA :53 S DATA :54 T DATA :55 U DATA :56 V DATA :57 W DATA :58 X DATA :59 Y DATA :5A Z DATA :5B [ DATA :5E ^ DATA :20 space DATA :00 (rept) DATA :08 char del DATA :10 cursor up DATA :11 cursor down DATA :12 cursor left DATA :13 cursor right DATA :09 tab DATA :80 ctrl DATA :00 (break) DATA :00 (shift) * ************************************ * ASCII TABLE LOWER CASE (SHIFTED) * ************************************ * KEYTS DATA :30 0 DATA :21 ! DATA :22 " DATA :23 # DATA :24 $ DATA :25 % DATA :26 & DATA :27 ' DATA :28 ( DATA :29 ) DATA :2A * DATA :2B + DATA :3C < DATA :3D = DATA :3E > DATA :3F ? DATA :0D car ret DATA :61 a DATA :62 b DATA :63 c DATA :64 d DATA :65 e DATA :66 f DATA :67 g DATA :68 h DATA :69 i DATA :6A j DATA :6B k DATA :6C l DATA :6D m DATA :6E n DATA :6F o DATA :70 p DATA :71 q DATA :72 r DATA :73 s DATA :74 t DATA :75 u DATA :76 v DATA :77 w DATA :78 x DATA :79 y DATA :7A z DATA :5D ] DATA :7E ~ DATA :20 space DATA :00 (rept) DATA :08 char del DATA :14 window up DATA :15 window down DATA :16 window left DATA :17 window right DATA :09 tab DATA :80 ctrl DATA :00 (break) DATA :00 (shift) * ************************************ * GET INPUTS FROM KEYBOARD OR DINC * ************************************ * * Part of RESET (C719). Determines input source * depending on 1st input done. * L3E143 CALL :D6BB Scan keyb; char in A RC Ready if break pressed RNZ Ready if key input done JMP :EFF4 Else: Get input from DINC * DATA :FF DATA :FF * ********************************************** * LOAD ASCII VALUE FOR KEY PRESSED IN BUFFER * ********************************************** * * From the key pressed, the offset to the start- * address of the ASCII table is calculated. The * ASCII value for the pressed key is stored in * the circular buffer KLIND. * * Entry: B : Column number. * C : Row number. * Exit: All registers preserved. * INKEY PUSH PSW PUSH B PUSH H MVI A,:07 ) SUB B ) ADD A ) Calc offset of startaddr ADD A ) for key pressed. ADD A ) Store it in C ADD C ) MOV C,A ) LHLD :02A7 Get startaddr ASCII table MVI B,:00 CPI :11 ) JC :E95D ) Check if key is a char CPI :2B ) A-Z JNC :E95D ) LDA :02C3 Get shift lock value MOV B,A in B L3E145 LDA :02B0 Get 'shift' byte XRA B Take CTRL into account ANI :40 A=#40 if shift, 00 when not JZ :E96C Jump if no shift PUSH D LXI D,:0038 Add. offset for lower case REM table DAD D Startaddr lower case table REM now in HL POP D L3E146 MVI B,:00 DAD B Add offset to startaddr MOV A,M Get ASCII value from table ORA A Check if Break, Rept, Shift JZ :E98E Then Pop, ret CPI :80 Check if CTRL JZ :E992 Then update CTRL flag MOV B,A Store ASCII value in B LHLD :02BE Get addr next pos in KLIND PUSH H Store KLIIN on stack CALL :D69C Update KLIND pointer LDA :02C0 Get lsbyte next output pos REM of KLIND CMP L Compare with KLIIN JZ :E98D Abort if buffer full SHLD :02BE Update KLIIN XTHL Get old KLIIN from stack MOV M,B Store ASCII char in KLIND L3E147 POP H L3E148 POP H POP B POP PSW RET REM * Update CTRL flag: REM L3E149 LDA :02C3 Get shiftlock value CMA Invert it STA :02C3 And store it again JMP :E98E Pop, ret * **************** * HEAP REQUEST * **************** * * The routine checks the heap for free areas. Evt. * consecutive free areas are consolidated. If this * procedure finds a free area min. 2 bytes larger * than requested, then it is reserved by setting * the length bytes (msb=0). An evt. resting free * area is set with length bytes and msb=1 (this * area must be >= 2 bytes). * The heap contents is never moved to obtain one * large consolidated area of free bytes!! * * Entry: DE: Length requested heap space. * Exit: AFBCDE preserved. * HL: Points to a 2-byte length of the re- * quested gap. If no space available, * it points to an error routine. * HREQ PUSH PSW PUSH B PUSH D MOV B,D ) Reqd length in BC MOV C,E ) LHLD :029B Get startaddr Heap HRQ10 MOV D,M ) INX H ) Contents 1st 2 bytes of MOV E,M ) Heap in DE (length) INX H ) MOV A,D 1st byte in A ANI :7F Mask bit 'free/used' CMP D MOV D,A D is length without msb JZ :D227 If area not free: check if REM end of heap reached. JMP REM #E9FA if not REM * If free area found: Check all next heap entries * and accumulate all free areas in succession: REM HRQ20 PUSH H Save startaddr area +2 DAD D Begin next area in HL MOV A,M ORA A Check msb of this area JP :E9C7 Jump if area occupied INX H MOV A,E ADD M Add lobyte length next area REM length previous area MOV E,A MOV A,D DCX H ADC M Add hibyte length next area REM length previous area ANI :7F Skip bit 'free/occupied' MOV D,A INX D INX D Add 2 extra bytes POP H Restore start free area +2 JMP :E9B0 Check next area REM * Next area is not free: REM HRQ30 POP H Restore start free area +2 PUSH H DCX H MOV M,E ) DCX H ) Store total free length in MOV A,D ) 1st 2 bytes of free area ORI :80 ) MOV M,A ) REM Space available here: HL pnt REM to start free area +2; DE is REM size free area; BC size reqd MOV A,E ) SUB C ) MOV L,A ) Calc free length - reqd. MOV A,D ) length; result in HL SBB B ) MOV H,A ) JM :E9F9 Space not sufficient: Leave REM consolidated area as free JNZ :E9E4 Jump if sufficient space ORA L JZ :E9F0 Jump if just enough DCR A JZ :E9F9 Not useable if 1 free byte REM left REM * Set not used part of free area to free: REM HRQ40 XCHG Addr free area in DE DCX D DCX D Reserve 2 bytes for length POP H Restore start free area +2 PUSH H DAD B Add reqd length to find REM start of resting free area MOV A,D ORI :80 Set free flag MOV M,A ) INX H ) Length free area into heap MOV M,E ) REM * Reserve area for requested entry: REM HRQ50 POP H Restore start free area +2 DCX H MOV M,C ) DCX H ) Reqd length in 1st 2 bytes MOV M,B ) POP D POP B POP PSW RET REM * Area too small: REM HRQ70 POP H Restore start free area HRQ75 DAD D HL pnts to next area JMP :E9A4 Check next area REM DATA :FF DATA :FF * * * * END